/***************************************************************
*  Copyright (c) 2007 by GroupMe! Team (www.groupme.net)
*  All rights reserved.
*
*  This file is part of the GroupMe! Project. Source code of 
*  this project is closed and redistribution of this code is
*  prohibited. 
*  
*  Contact: http://www.groupme.net
*
*  This copyright notice MUST APPEAR in all copies of the file!
***************************************************************/
package net.groupme.controller;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.groupme.controller.api.APIPropertyManager;
import net.groupme.exceptions.ExportFailedException;
import net.groupme.exceptions.ExportFailedServletException;
import net.groupme.exceptions.InsertFailedException;
import net.groupme.export.ExporterFactory;
import net.groupme.export.IExporter;
import net.groupme.export.RdfExport;
import net.groupme.export.Utils;
import net.groupme.model.Group;
import net.groupme.model.ObjectFactory;
import net.groupme.model.Resource;
import net.groupme.model.Tag;
import net.groupme.search.GroupMeSearchEngine;
import net.groupme.search.strategy.SearchBasedOnGroupContextPerformanceOptimized;
import net.groupme.search.strategy.TagSearchStrategyAmount;
import net.groupme.search.strategy.UserSpecificSearchStrategyImpl;

/**
 * created on Jul 7, 2007
 * 
 * @author Daniel Plappert
 * @author Fabian Abel, <a href="mailto:abel@l3s.de">abel@l3s.de</a>
 * @author last edited by: $Author: fabian $
 * 
 * @version $Revision: 1.9 $ $Date: 2008-05-07 18:17:57 $
 * @deprecated 
 */
public class ExportController extends HttpServlet {
	
    /** generated UID  */
    private static final long serialVersionUID = -3140745385924418568L;


    /** GroupMe! search engine FIXME: Search Engine aus dem ApplicationContext holen!!*/
    private GroupMeSearchEngine search = new GroupMeSearchEngine(
        new SearchBasedOnGroupContextPerformanceOptimized(), new TagSearchStrategyAmount(), new UserSpecificSearchStrategyImpl());


    /* API CONSTANTS */

    /** parameter which contains a tag */
    public static final String PARAMETER_TAG = APIPropertyManager.getString("api.tag");//$NON-NLS-1$

    /** parameter which contains a group id */
    public static final String PARAMETER_GROUP_ID = APIPropertyManager.getString("api.group.id");//$NON-NLS-1$

    /** parameter which contains a resource id */
    public static final String PARAMETER_RESOURCE_ID = APIPropertyManager.getString("api.resource.id");//$NON-NLS-1$    
    
    /** parameter which contains a parameter for export mode */
    public static final String PARAMETER_MODE = APIPropertyManager.getString("api.mode");//$NON-NLS-1$

    /** export mode parameter (resources) */
    public static final String PARAMETER_MODE_RESOURCES = APIPropertyManager.getString("api.mode.resources");//$NON-NLS-1$        

    /** export mode parameter (resources) */
    public static final String PARAMETER_MODE_GROUPS = APIPropertyManager.getString("api.mode.groups");//$NON-NLS-1$        

    /** parameter which contains a tag for search mode */
    public static final String PARAMETER_SEARCH_MODE = APIPropertyManager.getString("api.search.mode");//$NON-NLS-1$        

    /** search for all keywords */
    public static final String PARAMETER_SEARCH_MODE_ALL_TAGS = APIPropertyManager.getString("api.search.mode.allKeywords");//$NON-NLS-1$     

    /** search for one of the keywords */
    public static final String PARAMETER_SEARCH_MODE_ONE_TAG = APIPropertyManager.getString("api.search.mode.onlyOneKeyword");//$NON-NLS-1$        
    
    /** parameter which contains id of a user */
    public static final String PARAMETER_USER_ID = APIPropertyManager.getString("api.user.id");//$NON-NLS-1$

    /** parameter which contains the export format */
    public static final String PARAMETER_EXPORT_FORMAT = APIPropertyManager.getString("api.export.format");
    
    public static final String PARAMETER_MEDIA_TYPE = APIPropertyManager.getString("api.media.type");
    
    /** servlet description */
    public static final String SERVLET_DESCRIPTION = APIPropertyManager.getString("api.servlet.description"); //$NON-NLS-1$
    
	
    /** 
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     *
     * @param request servlet request
     * @param response servlet response
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        // Servlet things...
        response.setContentType("text/xml;charset=UTF-8"); //$NON-NLS-1$
        PrintWriter out = response.getWriter();
        IExporter exporter = null;
        
        // check, in which format the data should be exported
        if ( request.getParameter(PARAMETER_EXPORT_FORMAT) != null ) {
            exporter = ExporterFactory.getExporter(request.getParameter(PARAMETER_EXPORT_FORMAT));
        } else {
            // standard is rdf
            exporter = new RdfExport(); 
        }
        
        Collection<Tag> tagCollection = new HashSet<Tag>();        
        String mediaTypes[]; 
        
        /*
         * analyse parameters. For RDF export one of the following parameter must
         * be submitted:
         * tag:        keyword(s) the resource or group has(have)
         * groupID:    a special group has to be exported
         * resourceID: a special resource hat to be exported
         */
        if ( request.getParameter(PARAMETER_TAG) != null ) { //$NON-NLS-1$
            //analyse submitted keywords
            String tagValues[] = request.getParameterValues(PARAMETER_TAG); //$NON-NLS-1$
            
            for(String tagValue : tagValues) {
                
                try {
                    tagCollection.add(ObjectFactory.getTagForKeyword(tagValue));
                } catch (InsertFailedException ex) {
                    ex.printStackTrace();
                    throw new ServletException("Got exception from ObjectFactory. Message was: " + ex.getMessage());
                } //try-catch
                         
            } //for
            
            //analyse submitted media types
            mediaTypes = (request.getParameter(PARAMETER_MEDIA_TYPE) == null ? new String[] {} : request.getParameterValues(PARAMETER_MEDIA_TYPE));
            mediaTypes = Utils.analyseMediaTypes(mediaTypes);
            
        } else { 
            //if there are no keywords submitted, a special group or resource has to be exported
            if ( request.getParameter(PARAMETER_GROUP_ID) != null ) {
                
                int id = Integer.parseInt(request.getParameter(PARAMETER_GROUP_ID));
                exporter.setGroupDataByGroupId(id);
                
            } else if ( request.getParameter(PARAMETER_RESOURCE_ID) != null ) {
                
                int id = Integer.parseInt(request.getParameter(PARAMETER_RESOURCE_ID));
                exporter.setResourceDataByResourceId(id);                
                
            } else if ( request.getParameter(PARAMETER_USER_ID) != null ) {
                // read all groups of a user
                int id = Integer.parseInt(request.getParameter(PARAMETER_USER_ID));
                exporter.setDataByUserId(id);  
                
            } else {
                // there is nothing to export, throw exception
                throw new ExportFailedServletException("Export failed. Missing parameters. " +  
                    "Use one of the following: " + PARAMETER_TAG + ", " + PARAMETER_USER_ID + ", " + PARAMETER_GROUP_ID + " or " + PARAMETER_RESOURCE_ID);
            }
            
        }
        
        
        if ( request.getParameter(PARAMETER_TAG) != null && request.getParameter(PARAMETER_MODE) != null ) {
            //keywords are submitted, ...
            String exportMode = request.getParameter(PARAMETER_MODE);
           
            //optional parameter: find a group or resource with all or only one keyword
            boolean allTags = false;
            if ( request.getParameter(PARAMETER_SEARCH_MODE) != null ) {
                allTags = request.getParameter(PARAMETER_SEARCH_MODE).equals(PARAMETER_SEARCH_MODE_ALL_TAGS);
            }
            
            if ( exportMode.equals(PARAMETER_MODE_RESOURCES) ) {
                Collection<Resource> resources = search.searchForResources(tagCollection, allTags, true);
                exporter.setResourceData(resources);             
            } else if ( exportMode.equals(PARAMETER_MODE_GROUPS) ) {
                List<Group> groups = search.searchForGroups(tagCollection, allTags);
                exporter.setGroupData(groups);
            } else {
                throw new ExportFailedServletException("The export mode could not be detected. Possible values are \"" + 
                    PARAMETER_MODE_RESOURCES + "\" and \"" + PARAMETER_MODE_GROUPS + "\".");               
            }
            
        } else if (request.getParameter(PARAMETER_TAG) != null && request.getParameter(PARAMETER_MODE) == null) {
            throw new ExportFailedServletException("An error occurred. You send a keyword but the parameter \"" + PARAMETER_MODE + "\" is missing!");
        }
        
        // send RDF data to client
        String exportData = "";
        try {
            exporter.setUsedKeywords(tagCollection);
            exportData = exporter.doExport();            
        } catch ( ExportFailedException ex ) {
            throw new ExportFailedServletException("Data export failed because of the following error: " + ex.getMessage());
        }
        
        out.println(exportData);
    }
    
    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /** Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    }
    
    /** Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    }
    
    /** Returns a short description of the servlet.
     */
    public String getServletInfo() {
        return SERVLET_DESCRIPTION;
    }
    // </editor-fold>
}
